package thread;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author Janson
 * @Date 2022/2/24 15:31
 * @Version 1.0
 */
//多个线程同时操作同一个对象
// 买火车票的案例
// 发现问题： 当多个线程操作同一个资源时，线程不安全，数据出现紊乱
public class TestThread4Car implements Runnable {
    //票数
    private int ticket = 10;
    //采用 可重入锁，锁住会发生增、删、改 的数据，防止发生线程不安全情况
    ReentrantLock reentrantLock = new ReentrantLock();

    @Override
    public void run(){
        while (true){
            //上锁
            reentrantLock.lock();
            //加入线程延迟
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("线程延迟异常");
            }finally {
                if (ticket==0){
                    break;
                }

                System.out.println(Thread.currentThread().getName() + "拿到了第 "+ ticket-- + " 票");
                //解锁,必须放在 finally 里边执行，否则如果该线程异常，资源将永远不会被释放
                reentrantLock.unlock();
            }

        }
    }

    public static void main(String[] args) {
        TestThread4Car ticket = new TestThread4Car();
        new Thread(ticket,"小明").start();
        new Thread(ticket,"王咪").start();
        new Thread(ticket,"黄牛党").start();
    }
}
